/*
 * $Id$
 */
package py.windmill.action;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 *
 * @author myang
 */
public class SimpleUriTemplate implements UriTemplate {

    private String _path;
    private List<PathParameter> _params = Collections.emptyList();

    public SimpleUriTemplate(final String s) {
        final int i = s.indexOf("{");
        if (-1 == i) {
            _path = s;
        } else {
            _path = s.substring(0, i);
            _params = new ArrayList<PathParameter>();
            final String r = s.substring(i);
            int start = 0;
            PathParameter pp = null;
            while (null != (pp = param(r, start))) {
                _params.add(pp);
                start += pp.length();
            }
        }
    }

    /**
     *
     * @param s {name}postfix{name}postfix{name}...
     * @param start
     * @return
     */
    private PathParameter param(final String s, final int start) {
        if (start >= s.length()) {
            return null;
        }
        final int i = s.indexOf("{", start + 1);
        return param(i == -1 ? s.substring(start) : s.substring(start, i));
    }

    /**
     *
     * @param s {name=123}postfix
     * @return
     */
    private PathParameter param(final String s) {
        final int i = s.indexOf("}");
        if (-1 == i) { // parameter name is not closed
            throw new RuntimeException();
        } else if (1 == i) { // empty parameter name
            throw new RuntimeException();
        }

        final String var = s.substring(1, i);
        final int k = var.indexOf("=");
        String name = null, defaultVal = "";
        if (k == -1) {
            name = var;
        } else if (k == var.length()) { // missing default value
            throw new RuntimeException();
        } else {
            name = var.substring(0, k);
            defaultVal = var.substring(k + 1);
        }

        final int j = i + 1;
        final String postfix = (j == s.length() ? "" : s.substring(j));

        return new PathParameter(name, defaultVal, postfix);
    }

    @Override
    public Map<String, String> parse(final String uri) {
        final String s = uri.substring(_path.length());
        final Iterator<PathParameter> iter = _params.iterator();
        final Map<String, String> vals = new HashMap<String, String>();
        int i = 0;
        while (i < s.length() && iter.hasNext()) {
            final PathParameter pp = iter.next();
            final String pf = pp.postfix();
            final int j = s.indexOf(pf, i);
            if (j == -1 || pf.equals("")) {
                vals.put(pp.name(), s.substring(i));
                break;
            }
            else {
                vals.put(pp.name(), s.substring(i, j));
                i = (j + pf.length());
            }
        }

        while (iter.hasNext()) {
            final PathParameter pp = iter.next();
            vals.put(pp.name(), pp.defaultVal());
        }

        return vals;
    }

    public String path() {
        return _path;
    }

    public List<PathParameter> params() {
        return _params;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("<").append(_path);
        for (final PathParameter pp : _params) {
            sb.append(pp);
        }
        return sb.append(">").toString();
    }
}
